import re
import argparse
import sys
import os

class CodeAnalyzer:
    """代码分析器，用于统计代码行、空行、注释行"""
    
    def __init__(self):
        self.patterns = {
            'single_line_comment': r'^\s*#',  # 单行注释
            'multi_line_comment_start': r'^\s*"""',  # 多行注释开始
            'multi_line_comment_end': r'"""\s*$',  # 多行注释结束
            'blank_line': r'^\s*$'  # 空行
        }
    
    def analyze_code_file(self, filename):
        """分析代码文件，统计代码行、空行、注释行"""
        stats = {
            'code_lines': 0,
            'blank_lines': 0,
            'comment_lines': 0
        }
        
        try:
            with open(filename, 'r', encoding='utf-8') as file:
                lines = file.readlines()
            
            in_multi_line_comment = False
            
            for line in lines:
                line = line.rstrip()  # 去除行尾换行符和空白
                
                # 检查是否为空行
                if re.match(self.patterns['blank_line'], line):
                    stats['blank_lines'] += 1
                    continue
                
                # 检查是否在多行注释中
                if in_multi_line_comment:
                    stats['comment_lines'] += 1
                    # 检查多行注释是否结束
                    if re.search(self.patterns['multi_line_comment_end'], line):
                        in_multi_line_comment = False
                    continue
                
                # 检查多行注释开始
                if re.match(self.patterns['multi_line_comment_start'], line):
                    stats['comment_lines'] += 1
                    # 如果这一行没有同时结束多行注释，则标记进入多行注释状态
                    if not re.search(self.patterns['multi_line_comment_end'], line):
                        in_multi_line_comment = True
                    continue
                
                # 检查单行注释
                if re.match(self.patterns['single_line_comment'], line):
                    stats['comment_lines'] += 1
                    continue
                
                # 如果不是注释也不是空行，则为代码行
                stats['code_lines'] += 1
                
            return stats
            
        except Exception as e:
            print(f"代码分析错误: {e}")
            return stats


class WCTool:
    """文本计数统计工具 - 扩展功能版本"""
    
    def __init__(self):
        self.stats = {
            'char_count': 0,
            'word_count': 0,
            'sentence_count': 0,
            'line_count': 0,
            'code_lines': 0,
            'blank_lines': 0,
            'comment_lines': 0
        }
        self.code_analyzer = CodeAnalyzer()
    
    def count_chars(self, text):
        """统计字符数（包括空格和换行符）"""
        return len(text)
    
    def count_words(self, text):
        """统计单词数"""
        # 使用正则表达式匹配单词（字母序列）
        words = re.findall(r'\b[a-zA-Z]+\b', text)
        return len(words)
    
    def count_sentences(self, text):
        """统计句子数"""
        # 使用正则表达式匹配句子结束符 . ! ?
        sentences = re.findall(r'[^.!?]*[.!?]', text)
        return len(sentences)
    
    def is_code_file(self, filename):
        """判断文件是否为代码文件"""
        code_extensions = ['.py', '.java', '.cpp', '.c', '.h', '.js', '.html', '.css', 
                          '.php', '.rb', '.go', '.rs', '.swift', '.kt', '.ts']
        _, ext = os.path.splitext(filename)
        return ext.lower() in code_extensions
    
    def analyze_file(self, filename, analyze_code=False):
        """分析文件并返回统计结果"""
        try:
            with open(filename, 'r', encoding='utf-8') as file:
                content = file.read()
            
            # 基础统计
            self.stats['char_count'] = self.count_chars(content)
            self.stats['word_count'] = self.count_words(content)
            self.stats['sentence_count'] = self.count_sentences(content)
            self.stats['line_count'] = len(content.splitlines())
            
            # 代码分析（扩展功能）
            if analyze_code and self.is_code_file(filename):
                code_stats = self.code_analyzer.analyze_code_file(filename)
                self.stats.update(code_stats)
            elif analyze_code and not self.is_code_file(filename):
                print(f"警告: 文件 '{filename}' 不是支持的代码文件类型，跳过代码分析")
                self.stats['code_lines'] = 0
                self.stats['blank_lines'] = 0
                self.stats['comment_lines'] = 0
            
            return self.stats
            
        except FileNotFoundError:
            print(f"错误：文件 '{filename}' 未找到")
            sys.exit(1)
        except Exception as e:
            print(f"错误：读取文件时发生错误 - {e}")
            sys.exit(1)


def main():
    parser = argparse.ArgumentParser(
        description='文本计数统计工具 - 扩展功能版本',
        epilog='''
使用示例:
  %(prog)s file.txt                    # 显示基础统计
  %(prog)s -c file.txt                 # 仅统计字符数
  %(prog)s -w file.txt                 # 仅统计单词数
  %(prog)s -s file.txt                 # 仅统计句子数
  %(prog)s -l file.txt                 # 仅统计行数
  %(prog)s -a file.txt                 # 显示所有基础统计
  %(prog)s --code file.py              # 显示代码统计
  %(prog)s -a --code file.py           # 显示所有统计（包括代码统计）
        '''
    )
    
    # 基础功能参数
    parser.add_argument('filename', help='要分析的文件名')
    parser.add_argument('-c', '--chars', action='store_true', help='统计字符数')
    parser.add_argument('-w', '--words', action='store_true', help='统计单词数')
    parser.add_argument('-s', '--sentences', action='store_true', help='统计句子数')
    parser.add_argument('-l', '--lines', action='store_true', help='统计行数')
    parser.add_argument('-a', '--all', action='store_true', help='显示所有基础统计信息')
    
    # 扩展功能参数
    parser.add_argument('--code', action='store_true', 
                       help='统计代码行、空行、注释行（仅支持代码文件）')
    
    args = parser.parse_args()
    
    # 验证文件存在
    if not os.path.exists(args.filename):
        print(f"错误：文件 '{args.filename}' 不存在")
        sys.exit(1)
    
    wc = WCTool()
    stats = wc.analyze_file(args.filename, analyze_code=args.code)
    
    # 输出结果
    output_lines = []
    
    # 如果没有指定任何参数，默认显示所有基础统计
    show_all = not any([args.chars, args.words, args.sentences, args.lines, args.code])
    
    if args.chars or args.all or show_all:
        output_lines.append(f"字符数: {stats['char_count']}")
    
    if args.words or args.all or show_all:
        output_lines.append(f"单词数: {stats['word_count']}")
    
    if args.sentences or args.all or show_all:
        output_lines.append(f"句子数: {stats['sentence_count']}")
    
    if args.lines or args.all or show_all:
        output_lines.append(f"行数: {stats['line_count']}")
    
    # 代码统计输出
    if args.code:
        if wc.is_code_file(args.filename):
            output_lines.append(f"代码行: {stats['code_lines']}")
            output_lines.append(f"空行: {stats['blank_lines']}")
            output_lines.append(f"注释行: {stats['comment_lines']}")
        else:
            output_lines.append("代码统计: 不支持的文件类型")
    
    # 打印所有输出
    for line in output_lines:
        print(line)


if __name__ == '__main__':
    main()